package com.swh.cloud.biz.controll;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.swh.cloud.biz.provide.service.UserProvideService;
import com.swh.user.domain.UserEntity;

/**
 * 外部服务调用入口（restful）
 * @author sangwenhao-桑文豪
 * @date 2016年12月25日 下午1:34:09
 */
@EnableAutoConfiguration
@RestController
@RequestMapping("/userService")
public class UserController {
	
	@Autowired
	private UserProvideService userProvideService ;
	
	private static final Logger logger = LoggerFactory.getLogger(UserController.class) ;
	
    private static int byIDCount = 0 ;
    
    private static int byUnionCount = 0 ;
	
	@RequestMapping("/isSuccess")
	private String testIsStart(){
		return "user-cloud-biz-service server is start success! ";
	}
	
	/**
	 * 根据ID获取用户信息
	 * @param id
	 * @return
	 * @author sangwenhao-桑文豪
	 * @date 2016年12月25日 下午1:38:05
	 */
	//断路器 @HystrixCommand注解的方法失败后，系统将自动切换到fallbackMethod方法执行
    //断路器Hystrix具备回退机制、请求缓存和请求打包以及监控和配置等功能
    //这里用的是 回退机制
    //注意fallbackMethod的方法要对应的方法的入参和出参类型一致
    //@HystrixCommand(groupKey="getUserInfo", commandKey = "UserServer")//可自定义
    @HystrixCommand(fallbackMethod = "fallbackGetUserInfo",groupKey="cloud-service-UserController")
	@RequestMapping(value="/getUserInfo/{id}")
//	@ResponseBody
	public UserEntity getUserInfo(@PathVariable(value="id") Long id){
		//
		logger.info("id:"+id);
		if(id == null){
			id = 1L ;
		}
		UserEntity userEntity = userProvideService.getById(id);
		logger.info((byIDCount++)+" 返回值:"+ReflectionToStringBuilder.toString(userEntity));
		return userEntity ;
	}
    @HystrixCommand(fallbackMethod = "fallbackGetUserByUnion",groupKey="cloud-service-UserController")
	@RequestMapping(value="/getUserByUnion")
	public List<UserEntity> getUserByUnion(Map<String, UserEntity> paraMap) throws InterruptedException{
    	Thread.sleep(1000);
	    List<UserEntity> lists = userProvideService.getUserByUnion(paraMap);
	    logger.info((byUnionCount++)+" getUserByUnion 返回值数量："+lists.size());
	    return lists ;
	}
	
	//给appName赋值，${jdbc.driver} 可获取到 配置参数中的值
	@Value("${jdbc.url}")
    private String appName;

    @RequestMapping("/")
    public String getAppName() {
        return appName;
    }
    
  //回退方法
    @SuppressWarnings("unused")
    private UserEntity fallbackGetUserInfo(Long id) {
	 logger.info(">>>>>>>> UserController >>>>HystrixCommand fallbackMethod(fallbackGetUserInfo) handle!");
	 UserEntity user = new UserEntity();
	 user.setUserName("TestHystrixCommand->UserServer");
	 return user;
    }
    
    private List<UserEntity> fallbackGetUserByUnion(Map<String, UserEntity> paraMap){
	logger.info(">>>>>>>> UserController >>>>HystrixCommand fallbackMethod(fallbackGetUserByUnion) handle!");
	List<UserEntity> ls = new ArrayList<UserEntity>();
	 UserEntity user = new UserEntity();
	 user.setUserName("TestHystrixCommand");
	 ls.add(user);
	 return ls;
    }
    
    //从 Eureka Server发现服务实例
    //不要在@PostConstruct方法或@Scheduled方法使用EurekaClient（或任何ApplicationContext还没被启动的地方）。 
    @Autowired
    private EurekaClient discoveryClient;
    
    @RequestMapping("/serviceUrl")
    public String serviceUrl() {
        InstanceInfo instance = discoveryClient.getNextServerFromEureka("SHA-P07090124.deppon.com", false);
        return instance.getHomePageUrl();
    }
	
	public UserProvideService getUserProvideService() {
		return userProvideService;
	}

	public void setUserProvideService(UserProvideService userProvideService) {
		this.userProvideService = userProvideService;
	}

}
